/*
 * Exploder
 * 
 * Tero Pyylampi (218437), Jussi Tuurinkoski (211594)
 *
 * Wooden box element for the game
 */

#include "GameElementWoodBox.h"
#include "../../../GameCamera.h"
#include "../../../effects/GameEffects.h"
#include "../../../../Common.h"
#include "../../../../Resources.h"

#include "Box2D/Box2D.h"
#include <vector>

using namespace cocos2d;

// default constructor
GameElementWoodBox::GameElementWoodBox( b2World *world, cocos2d::CCLayer *layer, GameCamera *camera, bool editingMode, b2Vec2 worldPos, ElementType properties, float rotation )
	: GameConstructionElement( world, layer, camera, editingMode, properties ) {
	mInitialPosition.Set( worldPos.x, worldPos.y );
	
	// initialize element
	if( editingMode ) 
		initObjectInEditingMode( worldPos );
	else
		initObjectInGameMode( worldPos, rotation );
}

// default destructor
GameElementWoodBox::~GameElementWoodBox() {

}

// update function
void GameElementWoodBox::update( cocos2d::ccTime dt ) {
	GameConstructionElement::update( dt );
}

// apply explosion force, the object itself should decide whether to break or not
void GameElementWoodBox::applyExplosionToElements( b2Vec2 sourcePos, float force ) {
	GameConstructionElement::applyExplosionToElements( sourcePos, force );
}

// change object sprite to broken
void GameElementWoodBox::changeSpriteToBroken() {
	// TODO
}

// break object into pieces
void GameElementWoodBox::breakObject() {
	// save old position
	b2Vec2 currentPos = mBodies->at( 0 )->GetPosition();
	CCPoint screenPos = mGameCamera->convertWorldToScreen( currentPos.x, currentPos.y );

	// destroy old physics body
	mGameWorld->DestroyBody( mBodies->at( 0 ) );
	mBodies->clear();

	// remove sprite from layer
	mLayer->removeChild( mIntactSprite, true );
	mIntactSprite = 0;

	// create new bodies
	ObjectProperties properties( 1.0f, 0.7f, 0.2f );
	b2Body *b1 = this->createTriangle( false, 2.0f, 2.0f, currentPos.x - 0.5f + ( rand() % 100 / 100.0f ), currentPos.y - 0.5f + ( rand() % 100 / 100.0f ), properties, BOTTOM_LEFT );
	b2Body *b2 = this->createTriangle( false, 2.0f, 2.0f, currentPos.x - 0.5f + ( rand() % 100 / 100.0f ), currentPos.y - 0.5f + ( rand() % 100 / 100.0f ), properties, TOP_RIGHT );
	mBodies->push_back( b1 ); 
	mBodies->push_back( b2 );

	// insert sprites into layer
	for( unsigned int i = 0; i < 2; ++i ) {
		mLayer->addChild( mBrokenSprites[ i ], Z_LAYER_GAME_MIDDLE );
		mBrokenSprites[ i ]->release();
	}

	// match the positions
	update( 0 );

	// show effect
	// TODO: looks like a crap
	//cocos2d::CCParticleSystem *effect = GameEffects::createBreakingParticles( screenPos.x, screenPos.y, getResource( Textures::GAME_MISC_SPLINTER ), 15 );
	//mLayer->addChild( effect, Z_LAYER_GAME_FRONT );
}

// get the main type of the object
PhysicObjectItems GameElementWoodBox::getObjectType() {
	return ELEMENT_WOOD_BOX;
}

// init this object in editing mode
void GameElementWoodBox::initObjectInEditingMode( b2Vec2 worldPos ) {
	// create physics object
	ObjectProperties properties( 1.0f, 0.7f, 0.2f );
	b2Body *boxBody = createBox( true, 2.0f, 2.0f, worldPos.x, worldPos.y, properties );
	mBodies->push_back( boxBody );

	// create sprites
	mIntactSprite = CCSprite::spriteWithFile( getResource( Textures::GAME_ELEMENT_WOOD ) );
	mIntactSprite->setScale( RATEX * 0.32f );
	mLayer->addChild( mIntactSprite, Z_LAYER_GAME_MIDDLE );

	// init variables
	mCurrentlyActive = false;
}

// init this object in game mode
void GameElementWoodBox::initObjectInGameMode( b2Vec2 worldPos, float rotation ) {
	// create physics object
	ObjectProperties properties( 1.0f, 0.7f, 0.2f );
	b2Body *boxBody = createBox( false, 2.0f, 2.0f, worldPos.x, worldPos.y, properties );
	boxBody->SetTransform( boxBody->GetPosition(), rotation );
	mBodies->push_back( boxBody );

	// create normal sprite
	mIntactSprite = CCSprite::spriteWithFile( getResource( Textures::GAME_ELEMENT_WOOD ) );
	mIntactSprite->setScale( RATEX * 0.322f );
	mLayer->addChild( mIntactSprite, Z_LAYER_GAME_MIDDLE );

	// create broken sprites
	mBrokenSprites[ 0 ] = CCSprite::spriteWithFile( getResource( Textures::GAME_ELEMENT_WOOD_PART_A ) );
	mBrokenSprites[ 1 ] = CCSprite::spriteWithFile( getResource( Textures::GAME_ELEMENT_WOOD_PART_B ) );
	for( unsigned int i = 0; i < 2; ++i ) {
		mBrokenSprites[ i ]->setScale( RATEX * 0.322f );
		mBrokenSprites[ i ]->retain();
	}

	// init variables
	mObjectMaxDurability = 200.0f;
	mObjectDurabilityLeft = mObjectMaxDurability;

	if( mElementType == SHOULD_NOT_MOVE )
		setRedSpriteColors();
}
